home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 010 / games.arc / RUNOFF.BAS (.txt) < prev    next >
Encoding:
GW-BASIC  |  1980-01-01  |  13.9 KB  |  462 lines

  1. 10  REM  RUNOFF - A simple text formatter      February, 1982
  2. 20  REM
  3. 30  REM  COPYRIGHT 1982 John M. Nevison Associates, Concord, Mass.
  4. 32  REM  
  5. 34  REM  Timothy J. Stein
  6. 36  REM  John M. Nevison Associates
  7. 38  REM  Concord, Mass. 01742
  8. 40  REM  (617) 369 4214
  9. 42  REM
  10. 44  REM  Takes a text file and formats it for output to a line
  11. 46  REM  printer, screen, or another file. All lines starting with
  12. 48  REM  a period are considered formatting commands. The program
  13. 50  REM  recognizes these commands:
  14. 52  REM          .PAGE or .P             Force a new page
  15. 54  REM          .SPACING n or .S n      Set line spacing to n
  16. 56  REM          .LEFTMARGIN n or .LM n  Set left margin to column n
  17. 58  REM          .RIGHTMARGIN n or .RM n Set right margin to column n
  18. 60  REM          .JUSTIFY or .J          Fill lines to fit
  19. 62  REM          .NOJUSTIFY or .NJ       Don't bother
  20. 64  REM          .CENTER or .C           Center all lines
  21. 66  REM          .NOCENTER or .NC        Don't center any more
  22. 68  REM          .INCLUDE file or
  23. 70  REM            .I file               Read text from file specified
  24. 72  REM  
  25. 73  REM  A few notes:
  26. 74  REM  1. The program does not reassemble lines. If a line is longer
  27. 75  REM     than the distance from LM to RM it will be truncated.
  28. 76  REM     It will also not be justified or centered.
  29. 77  REM  2. The INCLUDE command cannot be nested. That is, an INCLUDED
  30. 78  REM     file cannot contain an INCLUDE command.
  31. 79  REM
  32. 80  REM  MAJOR VARIABLES:
  33. 81  REM          L$              The current line
  34. 82  REM          PAGE$           One page of lines
  35. 83  REM          V.xxx           Values used globally
  36. 84  REM          S.xxx           Switches used globally
  37. 85  REM
  38. 87  'PAGE
  39. 90  '------------------------------------------------------------------------
  40. 91  ' MAIN LOOP
  41. 92  '
  42. 93  ' 1. Set up initial values, get command names
  43. 94  ' 2. Get file names
  44. 95  ' 3. IF input file entered THEN
  45. 96  '      UNTIL eof seen on input file
  46. 97  '      1. Get a page of text
  47. 98  '      2. Send it out
  48. 99  ' 4. Close files and exit
  49. 100  '-----------------------------------------------------------------------
  50. 102  '
  51. 105  GOSUB 500                           'Initialize
  52. 110  GOSUB 2000                          'Get file names
  53. 120  IF INFILE$ = "" THEN 200
  54. 130    GOSUB 5000                        'Assemble a page
  55. 140    GOSUB 11000                       'Print it out
  56. 150    IF S.EOF = 0 THEN 130              'Until EOF
  57. 160  CLOSE
  58. 200  '
  59. 210  SYSTEM
  60. 390  'PAGE
  61. 400  '------------------------------------------------------------------------
  62. 500  'SUB: Initialize
  63. 510  '------------------------------------------------------------------------
  64. 515  '
  65. 520  DIM PAGE$(60)               'page of text
  66. 530  S.JUSTIFY = 0               'justify off
  67. 540  S.CENTER = 0                'center off
  68. 550  S.EOF = 0                   'not eof yet
  69. 560  S.PAGE = 0                  'not end of page yet
  70. 565  V.PAGE = 1                  'page number
  71. 567  V.INF = 1                   'current input file number
  72. 570  V.LM = 10                   'left margin value
  73. 580  V.RM = 70                   'right margin value
  74. 585  V.COL = V.RM - V.LM + 1     'current column width
  75. 590  V.SPACING = 1               'single spacing value
  76. 595  V.CC$ = "."                 'command character
  77. 597  V.PAGESIZE = 50             'page length
  78. 600  '
  79. 605  DATA 9 
  80. 606                              'number of commands (DIM if greater than 10)
  81. 610  DATA PAGE, P
  82. 620  DATA SPACING, S
  83. 630  DATA LEFTMARGIN, LM
  84. 640  DATA RIGHTMARGIN, RM
  85. 650  DATA JUSTIFY,J
  86. 660  DATA NOJUSTIFY, NJ
  87. 670  DATA CENTER, C
  88. 680  DATA NOCENTER, NC
  89. 685  DATA INCLUDE, I
  90. 690  '
  91. 700  READ NCMDS
  92. 710  FOR I = 1 TO NCMDS
  93. 720    READ CMD$(I), CMDA$(I)
  94. 730  NEXT I
  95. 740  '
  96. 750  RETURN
  97. 1900  'PAGE
  98. 1910  '-----------------------------------------------------------------------
  99. 1920  ' SUB: Get file names
  100. 1921  '      IN: none
  101. 1922  '     OUT: infile$ - input file name (null if none typed)
  102. 1930  '----------------------------------------------------------------------
  103. 1990  '
  104. 2000  CLS
  105. 2100  LOCATE 10,26
  106. 2110  INPUT "File: "; INFILE$
  107. 2120  IF INFILE$ = "" THEN 2410                'return
  108. 2130  ON ERROR GOTO 2160
  109. 2140  OPEN INFILE$ FOR INPUT AS #1
  110. 2150  GOTO 2220
  111. 2160  LOCATE 11,26
  112. 2170    IF ERR = 53 THEN 2200
  113. 2180       PRINT "File open error ";ERR
  114. 2190       GOTO 2210
  115. 2200    PRINT "No such file"
  116. 2210    RESUME 2100
  117. 2220  '
  118. 2225  V.INF = 1
  119. 2230  LOCATE 11,26
  120. 2240  INPUT "Output device: ";O$
  121. 2250  ON ERROR GOTO 2280
  122. 2260  OPEN O$ FOR OUTPUT AS #2
  123. 2270  GOTO 2310
  124. 2280    LOCATE 12,26
  125. 2290    PRINT "Illegal device, error ";ERR
  126. 2300    RESUME 2230
  127. 2310  '
  128. 2311  IF LEFT$(O$,3) <> "LPT" AND LEFT$(O$,3) <> "lpt" THEN 2318
  129. 2312     A$=CHR$(27)+"D"
  130. 2313     LPRINT A$;
  131. 2314     FOR I = 8 TO 64 STEP 8
  132. 2315       LPRINT CHR$(I);
  133. 2316     NEXT I
  134. 2317     PRINT #2,CHR$(0);
  135. 2318  '
  136. 2319  ON ERROR GOTO 0
  137. 2320  LOCATE 12,26
  138. 2330  PRINT "                              "
  139. 2410  RETURN
  140. 4900  'PAGE
  141. 4910  '-----------------------------------------------------------------------
  142. 5000  'SUB: Assemble a page
  143. 5001  '     IN: v.inf - input file number
  144. 5002  '    OUT: s.eof - if end of input file seen
  145. 5003  '         s.page - if .page command seen
  146. 5004  '         v.inf - changed if .include command seen
  147. 5005  '         linecount - number of lines this page
  148. 5006  '         page() - assembled page
  149. 5007  '-----------------------------------------------------------------------
  150. 5010  '
  151. 5020  LINECOUNT = 0
  152. 5030  GOSUB 5500                         'Get a good line
  153. 5040    IF S.EOF = 1 OR S.PAGE = 1 THEN 5100
  154. 5045      IF S.GOODLINE = 0 THEN 5070
  155. 5050        GOSUB 6000                    'Insert a line in the page
  156. 5060        IF LINECOUNT >= V.PAGESIZE THEN 5100
  157. 5070  GOTO 5030
  158. 5100  '
  159. 5110  RETURN
  160. 5400  'PAGE
  161. 5410  '-----------------------------------------------------------------------
  162. 5500  'SUB: Get a good line
  163. 5501  '     IN: v.inf - input file number
  164. 5502  '    OUT: l$ - line
  165. 5503  '         s.goodline - 0 if no text line, 1 if so
  166. 5504  '         v.inf - may have changed if .include seen
  167. 5505  '         s.eof - may be set if end of file seen
  168. 5507  '   NOTE: also processes commands seen; if .justify or .center are
  169. 5508  '         in effect, l$ is returned as justified or centered.
  170. 5509  '-----------------------------------------------------------------------
  171. 5510  '
  172. 5515  S.GOODLINE = 0
  173. 5520  IF EOF(V.INF) THEN 5585
  174. 5530    LINE INPUT #V.INF,L$
  175. 5540    LLEN = LEN(L$)
  176. 5550    IF LEFT$(L$,1) <> V.CC$ THEN 5560
  177. 5553      GOSUB 6500                     'Do command
  178. 5555      GOTO 5600
  179. 5560    IF S.JUSTIFY = 1 THEN GOSUB 8000 'Justify
  180. 5570    IF S.CENTER = 1 THEN GOSUB 8500  'Center line
  181. 5575    S.GOODLINE = 1
  182. 5580    GOTO 5600
  183. 5585  '
  184. 5587  IF V.INF = 1 THEN 5595
  185. 5589    CLOSE V.INF
  186. 5591    V.INF = 1
  187. 5593    GOTO 5520
  188. 5595  '
  189. 5597  S.EOF = 1
  190. 5600  '
  191. 5610  RETURN
  192. 5900  'PAGE
  193. 5910  '-----------------------------------------------------------------------
  194. 6000  'SUB: Insert a line
  195. 6001  '     IN: l$ - line to be inserted
  196. 6002  '         linecount - current number of lines this page
  197. 6003  '    OUT: page$() - page array
  198. 6004  '         linecount - modified to reflect line plus spacing
  199. 6005  '-----------------------------------------------------------------------
  200. 6010  '
  201. 6020  LINECOUNT = LINECOUNT + 1
  202. 6030  PAGE$(LINECOUNT) = LEFT$((SPACE$(V.LM-1) + L$),V.RM)
  203. 6040  IF V.SPACING <= 1 THEN 6100
  204. 6050    FOR I = 1 TO V.SPACING - 1
  205. 6060      LINECOUNT = LINECOUNT + 1
  206. 6070      PAGE$(LINECOUNT) = " "
  207. 6080    NEXT I
  208. 6100  '
  209. 6110  RETURN
  210. 6400  'PAGE
  211. 6410  '-----------------------------------------------------------------------
  212. 6500  'SUB: Do command
  213. 6501  '     IN: l$ - line with command on it (first char is ".")
  214. 6502  '    OUT: none
  215. 6503  '   NOTE: as side effect, the command is done
  216. 6504  '-----------------------------------------------------------------------
  217. 6510  '
  218. 6520  TPOS = 2
  219. 6530  GOSUB 9000                         'Get token
  220. 6540  IF TOKEN$ = "" THEN 6610
  221. 6550    FOR I = 1 TO NCMDS
  222. 6560      IF CMD$(I) = TOKEN$ THEN 6650
  223. 6570    NEXT I
  224. 6580    FOR I = 1 TO NCMDS
  225. 6590      IF CMDA$(I) = TOKEN$ THEN 6650
  226. 6600    NEXT I
  227. 6610    ERRX$ = "Illegal command <" + TOKEN$ + ">"
  228. 6620    GOSUB 10000                      'Print error
  229. 6630    GOTO 6690
  230. 6650  '
  231. 6660  ON I GOSUB 6700, 6800, 6900, 7000, 7100, 7200, 7300, 7400, 7500
  232. 6670  '
  233. 6690  RETURN
  234. 6695  'PAGE
  235. 6697  '-----------------------------------------------------------------------
  236. 6700  'SUB: page eject
  237. 6701  '-----------------------------------------------------------------------
  238. 6710  '
  239. 6720  S.PAGE = 1
  240. 6730  RETURN
  241. 6740  '
  242. 6790  '-----------------------------------------------------------------------
  243. 6800  'SUB: spacing
  244. 6801  '-----------------------------------------------------------------------
  245. 6810  '
  246. 6820  GOSUB 9300                         'Get value
  247. 6830  IF VALUE = -0.000999999 THEN VALUE = 1
  248. 6840    V.SPACING = VALUE
  249. 6850  RETURN
  250. 6860  '
  251. 6890  '-----------------------------------------------------------------------
  252. 6900  'SUB: left margin
  253. 6901  '-----------------------------------------------------------------------
  254. 6910  '
  255. 6920  GOSUB 9300
  256. 6930  IF VALUE = -0.000999999 THEN VALUE = 1
  257. 6940    IF V.RM > VALUE THEN 6947
  258. 6942       ERROR$ = "Left margin greater than right margin"
  259. 6944       GOSUB 10000
  260. 6946       GOTO 6950
  261. 6947    V.LM = VALUE
  262. 6948    V.COL = V.RM - V.LM + 1
  263. 6950  RETURN
  264. 6960  '
  265. 6990  '-----------------------------------------------------------------------
  266. 7000  'SUB: right margin
  267. 7001  '-----------------------------------------------------------------------
  268. 7010  '
  269. 7020  GOSUB 9300
  270. 7030  IF VALUE = -0.000999999 THEN VALUE = 1
  271. 7040    IF V.LM < VALUE THEN 7047
  272. 7042       ERROR$ = "Left margin greater than right margin"
  273. 7044       GOSUB 10000
  274. 7046       GOTO 7050
  275. 7047    V.RM = VALUE
  276. 7048    V.COL = V.RM - V.LM + 1
  277. 7050  RETURN
  278. 7060  '
  279. 7090  '-----------------------------------------------------------------------
  280. 7100  'SUB: justify
  281. 7101  '-----------------------------------------------------------------------
  282. 7110  '
  283. 7120  S.JUSTIFY = 1
  284. 7130  RETURN
  285. 7140  '
  286. 7190  '-----------------------------------------------------------------------
  287. 7200  'SUB: nojustify
  288. 7201  '-----------------------------------------------------------------------
  289. 7210  '
  290. 7220  S.JUSTIFY = 0
  291. 7230  RETURN
  292. 7240  '
  293. 7290  '-----------------------------------------------------------------------
  294. 7300  'SUB: center
  295. 7301  '-----------------------------------------------------------------------
  296. 7310  '
  297. 7320  S.CENTER = 1
  298. 7330  RETURN
  299. 7340  '
  300. 7390  '-----------------------------------------------------------------------
  301. 7400  'SUB: nocenter
  302. 7401  '-----------------------------------------------------------------------
  303. 7410  '
  304. 7420  S.CENTER = 0
  305. 7430  RETURN
  306. 7440  'PAGE
  307. 7490  '-----------------------------------------------------------------------
  308. 7500  'SUB: include
  309. 7501  '-----------------------------------------------------------------------
  310. 7510  '
  311. 7512  IF V.INF = 1 THEN 7520
  312. 7514    ERRX$ = "Cannot nest .include files"
  313. 7516    GOSUB 10000
  314. 7518    GOTO 7650
  315. 7520  GOSUB 9000                         'Get token
  316. 7530  ON ERROR GOTO 7560
  317. 7540  OPEN TOKEN$ FOR INPUT AS #3
  318. 7550    GOTO 7600
  319. 7560  ON ERROR GOTO 0
  320. 7570  ERRX$ = "Error opening .include file " + TOKEN$
  321. 7580  GOSUB 10000
  322. 7590  GOTO 7650
  323. 7600  '
  324. 7610  V.INF = 3
  325. 7620  '
  326. 7650  RETURN
  327. 7900  'PAGE
  328. 7910  '-----------------------------------------------------------------------
  329. 8000  'SUB: JUSTIFY
  330. 8001  '     IN: l$ - line to justify
  331. 8002  '         v.col - column width
  332. 8003  '    OUT: l$ - line justified
  333. 8004  '-----------------------------------------------------------------------
  334. 8010  '
  335. 8020  SCOUNT = 0
  336. 8030  FOR I = 1 TO LLEN
  337. 8040    IF MID$(L$,I,1) = " " THEN SCOUNT = SCOUNT + 1
  338. 8050  NEXT I
  339. 8060  IF SCOUNT = 0 THEN 8400
  340. 8070    LET SLOP = V.COL - LLEN
  341. 8080    IF SLOP <= 0 THEN 8400
  342. 8090    LET SSIZE = INT(SLOP/SCOUNT)
  343. 8100    LET SREM = SLOP - SSIZE * SCOUNT
  344. 8110    L2$ = L$
  345. 8120    L$ = ""
  346. 8130    FOR I = 1 TO LLEN
  347. 8140      X$ = MID$(L2$,I,1)
  348. 8150      L$ = L$ + X$
  349. 8160      IF X$ = " " THEN 8190
  350. 8180        GOTO 8300
  351. 8190      'else
  352. 8200        FOR J = 1 TO SSIZE
  353. 8210          L$ = L$ + " "
  354. 8230        NEXT J
  355. 8240        IF SREM <= 0 THEN 8300
  356. 8250          L$ = L$ + " "
  357. 8260          SREM = SREM - 1
  358. 8300    NEXT I
  359. 8310    LLEN = LEN(L$)
  360. 8320  '
  361. 8400  RETURN
  362. 8490  'PAGE
  363. 8495  '-----------------------------------------------------------------------
  364. 8500  'SUB: Center 
  365. 8501  '     IN: l$ - line to center
  366. 8502  '         v.col - column width
  367. 8503  '    OUT: l$ - line center
  368. 8504  '-----------------------------------------------------------------------
  369. 8510   '
  370. 8520  SLOP = V.COL - LLEN
  371. 8530  IF SLOP <= 0 THEN 8700
  372. 8540    L$ = SPACE$(SLOP/2) + L$
  373. 8550    LLEN = LEN(L$)
  374. 8560  '
  375. 8700  RETURN
  376. 8900  'PAGE
  377. 8910  '-----------------------------------------------------------------------
  378. 9000  'SUB: Get token
  379. 9001  '     IN: l$ - line in which to look for token
  380. 9002  '         tpos - character to start the search
  381. 9003  '         llen - length of line
  382. 9004  '    OUT: token$ - token found, or null if none
  383. 9005  '         tpos - moved to point to char after token
  384. 9007  '   NOTE: tokens delimited by spaces, leading spaces ignored, all
  385. 9008  '         alpha characters shift to upper case
  386. 9009  '-----------------------------------------------------------------------
  387. 9010  '
  388. 9020  TOKEN$ = ""
  389. 9030  FOR I = TPOS TO LLEN
  390. 9040    X$ = MID$(L$,I,1)
  391. 9050    IF X$ <> " " THEN 9080
  392. 9060  NEXT I
  393. 9070  GOTO 9250
  394. 9080  '
  395. 9090  FPOS = I
  396. 9100    FOR I = FPOS TO LLEN
  397. 9110      X$ = MID$(L$,I,1)
  398. 9120      IF X$ = " " THEN 9140
  399. 9130    NEXT I
  400. 9140  '
  401. 9150  TPOS = I + 1
  402. 9160  TOKEN$ = MID$(L$,FPOS,TPOS-FPOS-1)
  403. 9162  X = LEN(TOKEN$)
  404. 9164  FOR I = 1 TO X
  405. 9165    X$ = MID$(TOKEN$,I,1)
  406. 9166    IF X$ < "a" OR X$ > "z" THEN 9169
  407. 9167      X$ = CHR$(ASC(X$) - 32)
  408. 9168      MID$(TOKEN$,I,1) = X$
  409. 9169  NEXT I
  410. 9170  '
  411. 9250  RETURN
  412. 9290  'PAGE
  413. 9295  '-----------------------------------------------------------------------
  414. 9300  'SUB: get value
  415. 9301  '     IN: l$ - line to find value on
  416. 9302  '         tpos - place to start search
  417. 9303  '    OUT: value - numeric value of next token, or -.001 if none
  418. 9304  '         tpos - updated to point after token
  419. 9305  '-----------------------------------------------------------------------
  420. 9310  '
  421. 9320  GOSUB 9000                         'Get token
  422. 9330  ON ERROR GOTO 9400
  423. 9340    VALUE = VAL(TOKEN$)
  424. 9350    GOTO 9450
  425. 9400  RESUME 9410
  426. 9410  VALUE = -0.000999999
  427. 9420  '
  428. 9450  ON ERROR GOTO 0
  429. 9460  RETURN
  430. 9470  '
  431. 9900  'PAGE
  432. 9910  '-----------------------------------------------------------------------
  433. 10000  'SUB: print errors
  434. 10001  '----------------------------------------------------------------------
  435. 10010  '
  436. 10020  PRINT "ERROR: ";ERRX$;" in this line: "
  437. 10030  PRINT "   ";L$
  438. 10040  RETURN
  439. 11000  'SUB: print a page
  440. 11001  '     IN: page$() - page array
  441. 11002  '         linecount - number of lines assembled for this page
  442. 11003  '         v.page - current page number
  443. 11004  '    OUT: v.page - next page number
  444. 11005  '         s.page - reset to 0
  445. 11006  '----------------------------------------------------------------------
  446. 11010  '
  447. 11020  IF LINECOUNT > V.PAGESIZE THEN LINECOUNT = V.PAGESIZE
  448. 11030  FOR I = 1 TO LINECOUNT
  449. 11040    PRINT #2,PAGE$(I)
  450. 11050  NEXT I
  451. 11060  FOR I = 1 TO V.PAGESIZE - LINECOUNT + 4
  452. 11070    PRINT #2," "
  453. 11080  NEXT I
  454. 11090  PRINT #2,SPACE$((V.RM - 7)/2);"--";V.PAGE;"--"
  455. 11100  V.PAGE = V.PAGE + 1
  456. 11110  PRINT #2,CHR$(12)
  457. 11120  S.PAGE = 0
  458. 11130  RETURN
  459. 11140  END
  460. 11900  'PAGE
  461. 11910  '----------------------------------------------------------------------
  462.